package util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.Category;

import com.flaptor.indextank.apiclient.IndexDoesNotExistException;
import com.flaptor.indextank.apiclient.IndexTankClient;
import com.flaptor.indextank.apiclient.IndexTankClient.BatchResults;
import com.flaptor.indextank.apiclient.IndexTankClient.Document;
import com.flaptor.indextank.apiclient.IndexTankClient.Index;

public class IndexTankImport {

	private static final String INPUT_FILE = "c:/code/us.export.2011_03_07.tab";

	public static void main(String[] args) throws Exception {
		loadIndex();
	}

	public static boolean isInCategory(String category,
			String[] documentCategories) {
		for (String c : documentCategories) {
			if (c.equals(category))
				return true;
		}
		return false;
	}

	public static void loadIndex() throws IOException,
			IndexDoesNotExistException {
		long start = System.currentTimeMillis();
		BufferedReader input = new BufferedReader(new FileReader(INPUT_FILE));
		try {
			IndexTankClient client = new IndexTankClient(
					"http://something.api.indextank.com");
			Index index = client.getIndex("factual");

			int columns = 0;
			if (input.ready())
				columns = input.readLine().split("\\t").length; // Skip header row and grab column count.

			long docCount = 0;
			List<Document> documents = new ArrayList<Document>();
			List<Document> failedDocs = new ArrayList<Document>();

			while (input.ready()) {
				String line = input.readLine();
				String[] parts = line.split("\\t", columns);

				String[] cats = Category.splitCategory(parts[8]);
				if (!isInCategory("Food & Beverage", cats))
					continue;

				Map<String, String> fields = new HashMap<String, String>();
				fields.put("text", line);
				fields.put("name", parts[1]);
				fields.put("address", parts[2]);
				fields.put("city", parts[3]);
				fields.put("state", parts[4]);
				fields.put("postcode", parts[5]);
				fields.put("telephone", parts[6]);
				fields.put("fax", parts[7]);
				fields.put("category", parts[8]);
				fields.put("website", parts[9]);
				fields.put("latitude", parts[10]);
				fields.put("longitude", parts[11]);

				Map<String, String> categories = new HashMap<String, String>();
				categories.put("citystate", parts[3] + " " + parts[4]);
				switch (cats.length) {
					case 3 :
						categories.put("category3", cats[2]);
					case 2 :
						categories.put("category2", cats[1]);
					case 1 :
						categories.put("category1", cats[0]);
					default :
						break;
				}

				Map<Integer, Float> variables = new HashMap<Integer, Float>();
				if (parts[10] != null && parts[10].length() > 0
						&& parts[11] != null && parts[11].length() > 0) {
					variables.put(0, Float.parseFloat(parts[10]));
					variables.put(1, Float.parseFloat(parts[11]));
				}

				documents
						.add(new Document(parts[0], fields, variables, categories));
				docCount++;

				// Every 1000 documents, batch write them.
				if (docCount % 1000 == 0) {
					BatchResults batchResults = index.addDocuments(documents);
					documents.clear();

					if (batchResults.hasErrors()) {
						for (int i = 0; i < 1000; i++) {
							boolean success = batchResults.getResult(i);
							if (!success) {
								/* Requires patch of IndexTank API */
								//								System.out.println("Doc failed: "
								//										+ batchResults.getDocument(i).getId()
								//										+ "; error: " + batchResults.getErrorMessage(i));
							}
						}

						for (Document doc : batchResults.getFailedDocuments()) {
							failedDocs.add(doc);
						}
					}
				}
			}

			// Write any remainder documents.
			if (documents.size() > 0) {
				index.addDocuments(documents);
			}

			long end = System.currentTimeMillis();

			System.out.println("Indexed " + docCount + " documents.");
			System.out.println("Failed " + failedDocs.size() + ".");
			System.out.println("Took " + (end - start) + " ms.");

		} finally {
			input.close();
		}
	}
}
